﻿using Masuit.Tools;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using SharpGrip.FluentValidation.AutoValidation.Mvc.Extensions;
using SharpGrip.FluentValidation.AutoValidation.Mvc.Results;

namespace SimpleX
{
    public static partial class ServicesExtension
    {
        public static IServiceCollection AddFluent(this IServiceCollection services)
        {
            services.AddFluentValidationAutoValidation(configuration =>
            {
                //一些简单的实体验证可以直接在上面标记 [Required] 非空
                //复杂的可以使用 public class StudentInputValidation : AbstractValidator<StudentInput>, IScoped
                //这些都是验证前台的一些方法,也就是Control里传过来的

                //当然也支持手动验证[可用于Service内部调用验证],上面的继承了IScoped,所以你懂的,直接注入 IValidator<StudentInput> validator
                //然后调用 ValidationResult result = await _validator.ValidateAsync(person);

                // Disable the built-in .NET model (data annotations) validation. 设置成false可兼容.Net自带的模型验证
                configuration.DisableBuiltInModelValidation = false;

                // Only validate controllers decorated with the `FluentValidationAutoValidation` attribute.
                configuration.ValidationStrategy = SharpGrip.FluentValidation.AutoValidation.Mvc.Enums.ValidationStrategy.All;

                // Enable validation for parameters bound from `BindingSource.Body` binding sources.
                configuration.EnableBodyBindingSourceAutomaticValidation = true;

                // Enable validation for parameters bound from `BindingSource.Form` binding sources.
                configuration.EnableFormBindingSourceAutomaticValidation = true;

                // Enable validation for parameters bound from `BindingSource.Query` binding sources.
                configuration.EnableQueryBindingSourceAutomaticValidation = true;

                // Enable validation for parameters bound from `BindingSource.Path` binding sources.
                configuration.EnablePathBindingSourceAutomaticValidation = true;

                // Enable validation for parameters bound from 'BindingSource.Custom' binding sources.
                configuration.EnableCustomBindingSourceAutomaticValidation = true;

                // Replace the default result factory with a custom implementation.
                configuration.OverrideDefaultResultFactoryWith<CustomResultFactory>();
            });

            return services;
        }

        public class CustomResultFactory : IFluentValidationAutoValidationResultFactory
        {
            public IActionResult CreateActionResult(ActionExecutingContext context, ValidationProblemDetails validationProblemDetails)
            {
                var errorMessages = new StringBuilder();
                foreach (var error in validationProblemDetails.Errors)
                    errorMessages.AppendLine($"[{error.Key}]{error.Value.Join()}");

                var unify = new UnifyResult<object>
                {
                    Code = HttpStatusCode.BadRequest,
                    Msg = errorMessages.ToString(),
                    Exts = Unify.Read(),
                    Timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
                };

                return new BadRequestObjectResult(unify);
            }
        }
    }
}